package com.hnx.admin.aurora.system.service.impl;

import com.hnx.admin.aurora.api.cache.CacheAPI;
import com.hnx.admin.aurora.redis.RedisCache;
import com.hnx.admin.aurora.system.domain.convert.dept.DeptConvert;
import com.hnx.admin.aurora.system.domain.dto.dept.entity.DeptDTO;
import com.hnx.admin.aurora.system.domain.dto.role.entity.RoleDTO;
import com.hnx.admin.aurora.system.domain.param.dept.form.DeptForm;
import com.hnx.admin.aurora.system.domain.param.dept.query.DeptQuery;
import com.hnx.admin.aurora.system.mapper.dept.DeptMapper;
import com.hnx.admin.aurora.system.mapper.role.RoleMapper;
import com.hnx.admin.aurora.system.service.DeptService;
import com.hnx.admin.aurora.utils.TreeUtil;
import com.hnx.admin.aurora.web.json.ResultJson;
import com.hnx.admin.aurora.web.json.TreeNodeVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;

/*
创建人： 倔强的头发
创建时间：2025/6/18
功能描述:

*/
@Service
@RequiredArgsConstructor
public class DeptServiceImpl implements DeptService, CacheAPI {
    private final DeptMapper deptMapper;
    private final DeptConvert deptConvert;
    private final RedisCache redisCache;
    private final RoleMapper roleMapper;
    @Override
    public List<TreeNodeVO> selectDeptList(DeptQuery dept) {
        List<DeptDTO> depts = deptMapper.selectDeptList(dept);
        List<TreeNodeVO> tree = deptConvert.toTreeList(depts);
        List<TreeNodeVO> treeList = TreeUtil.buildTree(tree, TreeNodeVO::getId, Comparator.comparing(TreeNodeVO::getOrderNum));
        return treeList;
    }

    @Override
    public ResultJson selectDeptTreeList(String roleId) {
        List<TreeNodeVO> list = deptMapper.selectDeptTreeList(null);
        return ResultJson.success().add("depts", TreeUtil.buildTree(list,TreeNodeVO::getId,Comparator.comparing(TreeNodeVO::getOrderNum))).add("checkedKeys", selectDeptListByRoleId(roleId));
    }

    @Override
    public List<String> selectDeptListByRoleId(String roleId) {
        RoleDTO role = roleMapper.selectRoleById(roleId);
        return deptMapper.selectDeptListByRoleId(roleId, role.isDeptCheckStrictly());
    }

    @Override
    public ResultJson selectList(DeptQuery dept) {
        List<DeptDTO> depts = deptMapper.selectDeptList(dept);
        return ResultJson.success().add("data", depts);
    }

    @Override
    public ResultJson insertDept(DeptForm dept) {
        List<DeptDTO> list = selectDeptAll();
        if(list.stream().anyMatch(n->n.getDeptId().equals(dept.getParentId()) && n.getStatus().equals("1"))){
            throw new RuntimeException("父节点状态已停用，不能新增部门");
        }
        int res = deptMapper.insertDept(dept);
        if(res > 0){
            if(redisCache.hasKey(SYS_DEPT_KEY)){
                redisCache.deleteObject(SYS_DEPT_KEY);
            }
        }
        return ResultJson.condition(res);
    }

    @Override
    public ResultJson selectDeptById(String deptId) {
        DeptDTO dept = deptMapper.selectDeptById(deptId);
        return ResultJson.data(dept);
    }

    @Override
    public ResultJson deleteDeptById(String deptId) {
        List<DeptDTO> list = selectDeptAll();
        if(list.stream().anyMatch(n->n.getParentId().equals(deptId))){
            throw new RuntimeException("存在下级部门，不能直接删除");
        }
        if (deptMapper.checkDeptExistUser(deptId))
        {
            throw new RuntimeException("部门存在用户,不允许删除");
        }
        int res = deptMapper.deleteDeptById(deptId);
        if(res >0){
            if(redisCache.hasKey(SYS_DEPT_KEY)){
                redisCache.deleteObject(SYS_DEPT_KEY);
            }
        }
        return ResultJson.condition(res);
    }

    @Override
    public ResultJson updateDept(DeptForm dept) {
        if(dept.getDeptId() == dept.getParentId()){
            throw new RuntimeException("上级部门不能是自己");
        }
        int result = deptMapper.updateDept(dept);
        if(result >0){
            if(redisCache.hasKey(SYS_DEPT_KEY)){
                redisCache.deleteObject(SYS_DEPT_KEY);
            }
        }
        return ResultJson.condition(result);
    }

    private List<DeptDTO> selectDeptAll(){
        return redisCache.getCacheList(SYS_DEPT_KEY,DeptDTO.class).orElseGet(()->{
            List<DeptDTO> list = deptMapper.selectDeptList(new DeptQuery());
            if(Objects.nonNull(list) && list.size() > 0){
                redisCache.setCacheList(SYS_DEPT_KEY,list);
            }
            return list;
        });
    }
}
